
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Vector;
import javax.microedition.lcdui.Image;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author thien
 */
public class DataHandler implements Runnable{




    static DataInputStream dataInputStream;
    static DataOutputStream dataOutputStream;
    Thread thread;
    private long delay = 60;
   
    
    public static final byte TEXT = 1;
    public static final byte IMAGE = 2;
    public static final byte ICON = 3;
    public static final byte NOTE = 4;

    public static final int REQUEST_USER = 101;
    private static final int REQUEST_NOTE = 102;
    public static final int REQUEST_TEXT = 103;   
    public static final int REQUEST_ICON = 104;    
    public static final int REQUEST_IMAGE = 105;
    public static final int REQUEST_LIST = 106;
    public static final int REQUEST_MANGA = 107;
    public static final int REQUEST_END_LIST = 108;
    public static final int REQUEST_END_READ = 109;
    public static final int REQUEST_END_SYSTEM = 110;
    
    public static final int REQUEST_ERROR_ICON = 111;
    public static final int REQUEST_ERROR_IMG = 112;
    
        
    public static final int HANDLED_USER = 201;
    public static final int HANDLED_IMAGE = 202;
    public static final int HANDLED_ICON = 203;
    public static final int HANDLED_LIST = 204;
    public static final int HANDLED_TEXT = 205;
    public static final int HANDLED_MANGA = 206;
    public static final int HANDLED_END_READ = 207;
    public static final int HANDLED_END_SYSTEM = 208;
    public static final int HANDLED_END_LIST = 209;
    public static final int SEND_ADDRESS=210;
    public static final int SEND_SUBJ=211;
    public static final int SEND_CONTENT=212;
     public static final int SEND_ACTION=213;

    
    
    byte[] note;
    
    

    private boolean dataAvailabe;

    public boolean isDataAvailabe() {
        return dataAvailabe;
    }
    private int handled = 0;
    public boolean username_Authenticate = false;
    
    Vector textVector = new Vector();

    public Vector getIconVector() {
        return iconVector;
    }

    public Vector getImageVector() {
        return imageVector;
    }

    public Vector getTextVector() {
        return textVector;
    }
    Vector imageVector = new Vector();
    Vector iconVector = new Vector();
    Vector queue = new Vector();
    Vector segmentImgVector = new Vector();
    Vector segmentTextVector = new Vector();
    Vector imgDataVector = new Vector();
    
    int count = 0;
    int countIcon = 0;
    public class SegmentImage{
        Vector byteImgVector = new Vector();
        Image image;
        byte kind;
        String name;
        public SegmentImage(String name,byte kind){
            this.name = name;
            this.kind = kind;
        }
        public Image getImage(byte[] lastBytes){
            int length = 0;
            for(int i=0;i<byteImgVector.size();i++){
                byte[] b = (byte[])byteImgVector.elementAt(i);
                length+= b.length;
            }  
            byte[] imageData = new byte[length+lastBytes.length];
            int start = 0;
            for(int i=0;i<byteImgVector.size();i++){
                byte[] b = (byte[])byteImgVector.elementAt(i);
                System.arraycopy(b, 0, imageData, start, b.length);
                start+=b.length;
            }
            
            System.arraycopy(lastBytes, 0, imageData, start, lastBytes.length);
            
                       
            image = Image.createImage(imageData,0,imageData.length);

            if(kind==ICON){
                iconVector.addElement(new ImageBuffer(image, name));
                System.out.println("get icon "+name);

            }
            else if(kind==IMAGE){
                imageVector.addElement(new ImageBuffer(image, name));                            
                System.out.println("get image "+name);

            }
//                if(request==REQUEST_ICON){
//                    try{
//                        iconVector.addElement(new ImageData(image));
//                        System.out.println("add icon "+iconVector.size());                        
//                    }
//                    catch(Exception e){
//                        System.out.println("segment gets icon "+e.toString());
//                        segmentImgVector.removeAllElements();
//                        iconVector.removeAllElements();
//                        try {
//                            dataOutputStream.writeInt(REQUEST_ICON);
//                            dataOutputStream.flush();
//                        } catch (IOException ex) {
//                            ex.printStackTrace();
//                        }                        
//                    }
//                }
//                else{
//                    try{
//                        imageVector.addElement(new ImageData(image));
//                        System.out.println("add image "+imageVector.size());                         
//                    }
//                    catch(Exception e){
//                        System.out.println("segment gets image "+e.toString());
//                        segmentImgVector.removeElementAt(segmentImgVector.size()-1);
//                        try {
//                            dataOutputStream.writeInt(REQUEST_IMAGE);
//                            dataOutputStream.flush();
//                        } catch (IOException ex) {
//                            ex.printStackTrace();
//                        }
//                    }                 
//                }

            return image;
        }
    }
      
    public class SegmentText{
        String text;
        Vector byteTextVector = new Vector();
        public String getText(byte[] lastBytes){
            int length = 0;
            for(int i=0;i<byteTextVector.size();i++){
                byte[] b = (byte[])byteTextVector.elementAt(i);
                length+= b.length;
            }  
            byte[] textData = new byte[length+lastBytes.length];
            int start = 0;
            for(int i=0;i<byteTextVector.size();i++){
                byte[] b = (byte[])byteTextVector.elementAt(i);
                System.arraycopy(b, 0, textData, start, b.length);
                start+=b.length;
            }
            System.arraycopy(lastBytes, 0, textData, start, lastBytes.length);
           
            try{
                text = new String(textData,"UTF-8");
                textVector.addElement(text);
                System.out.println("get text: "+text);
            }
            catch(Exception e){
                System.out.println("error text UTF "+e);
            }
            return text;
        }
    }
    
        
    public void resetStream(){
        segmentImgVector.removeAllElements();
        segmentTextVector.removeAllElements();
        imageVector.removeAllElements();
        iconVector.removeAllElements();
        textVector.removeAllElements();
    }
    public DataHandler(DataOutputStream dataOutputStream,DataInputStream dataInputStream){
        DataHandler.dataInputStream = dataInputStream;
        DataHandler.dataOutputStream = dataOutputStream;
        start();
    }
    
//    public DataHandler(DataOutputStream dataOutputStream,DataInputStream dataInputStream){
//        dataInputStream = dataInputStream;
//        dataOutputStream = dataOutputStream;
//        imageVector = mangaCanvas.imageVector;
//        textVector = mangaCanvas.textVector;
//        iconVector = mangaCanvas.iconVector;
//        note = mangaCanvas.note;
//        start();
//    }
    
    private void start(){
        thread = new Thread(this);
        thread.start();
    }
    
    public void readData() {
        try {
            if(dataInputStream.available()>0){
                dataAvailabe = true;
                byte[] b = new byte[dataInputStream.available()];
                dataInputStream.read(b);
                queue.addElement(b);
            }
            else{
                dataAvailabe = false;
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    private void handleData(){
        if(queue.size()>0){
            byte[] b = (byte[])queue.elementAt(0);
            byte[] req = new byte[4];
            System.arraycopy(b, 0, req, 0, 4);
            int request = byteArrayToInt(req);
            if(request==REQUEST_USER){
                userHanlder(b);
            }
            else if(request==REQUEST_LIST){
                textHandler(b, HANDLED_LIST);
            }       
            else if(request==REQUEST_NOTE){
                handleNote(b);
            }
            else if(request==REQUEST_MANGA){
                if(b[4]==TEXT){  
                    textHandler(b, HANDLED_MANGA);
                }                     
                else if(b[4]==NOTE){
                    textHandler(b, HANDLED_MANGA); 
                }
                else if(b[4]==IMAGE||b[4]==ICON){
                    imageHandler(b, HANDLED_MANGA);  
                }
            }
            else if(request==REQUEST_TEXT){
                textHandler(b,HANDLED_TEXT);
            }
            else if(request==REQUEST_END_READ){
                textHandler(b,HANDLED_END_READ);
            }
            else if(request==REQUEST_END_SYSTEM){
                textHandler(b,HANDLED_END_SYSTEM);
            }
            else if(request==REQUEST_END_LIST){
                textHandler(b,HANDLED_END_LIST);
            }
            else if(request==REQUEST_ERROR_ICON){
                imageHandler(b, HANDLED_ICON);
            }
            else if(request==REQUEST_ERROR_IMG){
                imageHandler(b, HANDLED_IMAGE);
            }
            queue.removeElementAt(0);
        }
    }
    
    
    
    public String getText(){
        String text = (String)textVector.firstElement();
        return text;

    }
    
    public void removeText(){
        if(!textVector.isEmpty())
            textVector.removeElementAt(0);
//        if(textVector.isEmpty()){
//            resetHandle();
//        }
    }
    
    public ImageBuffer getIcon(){
        ImageBuffer imageBuffer = (ImageBuffer)iconVector.firstElement();


        return imageBuffer;
    }
    public void removeIcon(){
        if(!iconVector.isEmpty())
            iconVector.removeElementAt(0);
//        if(iconVector.isEmpty())
//            resetHandle();
    }
    
    public ImageBuffer getImage(){
        ImageBuffer imageBuffer = (ImageBuffer)imageVector.firstElement();
        return imageBuffer;
    }
    
    public void removeImage(){
        if(!imageVector.isEmpty())
            imageVector.removeElementAt(0);
//        if(imageVector.isEmpty()){
//            resetHandle();
//        }
    }
    public int getHandle(){
        return handled;
    }
    
    public void resetHandle(){
        handled = 0;
    }
   
    public int byteArrayToInt(byte [] b) {
        return (b[0] << 24)
                + ((b[1] & 0xFF) << 16)
                + ((b[2] & 0xFF) << 8)
                + (b[3] & 0xFF);
    }
    
    private void userHanlder(byte[] b){
        if(b[9]==0){
            username_Authenticate = false;
        }
        else{
            username_Authenticate = true;
        }
        handled = HANDLED_USER;
    }
    
    private void handleNote(byte[] b){
        note[0] = b[4];
    }
    
    private void imageHandler(byte[] b,int handle){  


        byte[] buffer = new byte[4];
        int lengthName = b[5];        
        if(segmentImgVector.isEmpty()){  
            byte[] nameBuffer = new byte[lengthName];
            System.arraycopy(b, 6, nameBuffer, 0, lengthName);
            String name;
            try {
                name = new String(nameBuffer,"UTF-8");
                segmentImgVector.addElement(new SegmentImage(name,b[4]));
            } catch (UnsupportedEncodingException ex) {
                System.out.println("error "+ex);
            }
        }
        System.arraycopy(b, 6+lengthName, buffer, 0, 4); // index
        int index = byteArrayToInt(buffer);
        
        System.arraycopy(b, 10+lengthName, buffer, 0, 4); // segment
        int segment = byteArrayToInt(buffer);
        
        System.arraycopy(b, 14+lengthName, buffer, 0, 4); // length
        int length = byteArrayToInt(buffer);
    
        byte[] segmentByte = new byte[length];
        System.arraycopy(b, 18+lengthName, segmentByte, 0, length);
        SegmentImage segmentImage = (SegmentImage)segmentImgVector.firstElement();
        if(segment==-1){
            try{
                segmentImage.getImage(segmentByte);
                this.handled = handle;
                segmentImgVector.removeElementAt(0);
            }
            catch(Exception e){
                System.out.println("error image "+e);      
                if(!segmentImgVector.isEmpty())
                        segmentImgVector.removeElementAt(0);
                if(b[4]==ICON){
                    try {
                        DataHandler.requestData(REQUEST_ERROR_ICON, index);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
                else if(b[4]==IMAGE){
                    try {
                        DataHandler.requestData(REQUEST_ERROR_IMG, index);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }                    
                }
            }
        }
        else{
            segmentImage.byteImgVector.addElement(segmentByte); 
        }    



    }
    
    
    private void textHandler(byte[] b,int handle){

        byte[] buffer = new byte[4];
        System.arraycopy(b, 5, buffer, 0, 4);
        int segment = byteArrayToInt(buffer);  
        if(segmentTextVector.isEmpty()){
            segmentTextVector.addElement(new SegmentText());
        }
        System.arraycopy(b, 9, buffer, 0, 4);
        int length = byteArrayToInt(buffer);
        byte[] segmentByte = new byte[length];
        System.arraycopy(b, 13, segmentByte, 0, length);
        SegmentText segmentText = (SegmentText)segmentTextVector.firstElement();
        if(segment==-1){
            try{
                segmentText.getText(segmentByte);
                this.handled = handle;
                segmentTextVector.removeElementAt(0);
            }
            catch(Exception e){
                System.out.println("text error "+e);
            }
        }
        else{
            segmentText.byteTextVector.addElement(segmentByte);
        }
    }
    
    

    public boolean hasImageData(){
        if(textVector.isEmpty()&&iconVector.isEmpty()&&imageVector.isEmpty()){
            return false;
        }
        return true;
    }
    
    public static void requestAuthentication(int request,String string) throws IOException{
        dataOutputStream.writeInt(request);
        dataOutputStream.writeUTF(string);
        dataOutputStream.flush();
    }
     public static void sendData(int request,String string) throws IOException{
        dataOutputStream.writeInt(request);
        if (string !=null)
                 {

        dataOutputStream.writeUTF(string);
         }
        dataOutputStream.flush();
    }

    public static void requestData(int request,int kind) throws IOException{
        dataOutputStream.writeInt(request);
        dataOutputStream.writeInt(kind);
        dataOutputStream.flush();
    }
    
    
    public void close(){
        thread = null;
        resetStream();
    }
    
    
    
    public void run() {
        Thread currentThread = Thread.currentThread();
        while(currentThread == thread){
            long startTime = System.currentTimeMillis();

            readData();
            handleData();

            long timeTake = System.currentTimeMillis() - startTime;
            if(timeTake < delay){
                synchronized(this){
                    try {
                        wait(delay - timeTake);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
            else {
                    Thread.yield();
            }
        }
    }
}

